const PENDING = 'PENDING';
const FULFILLED = 'FULFILLED';
const REJECTED = 'REJECTED';

class myPromise {
  constructor(executor) {
    this.status = PENDING;
    this.value = undefined;
    this.reason = undefined;
    this.onResolveCallbacks = [];
    this.onRejectedCallbacks = [];

    let resolve = value => {
      if (value instanceof myPromise) {
        return value.then(resolve, reject);
      }
      if (this.status === PENDING) {
        this.status = FULFILLED;
        this.value = value;
        this.onResolveCallbacks.forEach(cb => cb(this.value));
      }
    }

    let reject = reason => {
      if (this.status === PENDING) {
        this.status = REJECTED;
        this.reason = reason;
        this.onResolveCallbacks.forEach(cb => cb(this.reason));
      }
    }

    try {
      executor(resolve, reject);
    } catch (error) {
      reject(error);
    }
  }

  then(onFulfilled, onRejected) {
    if (this.status === FULFILLED) {
      onFulfilled(this.value);
    }

    if (this.status === REJECTED) {
      onRejected(this.reason);
    }

    if (this.status === PENDING) {
      this.onResolveCallbacks.push(onFulfilled)
      this.onRejectedCallbacks.push(onRejected)
    }
  }

  static resolve(data) {
    return new myPromise((resolve, reject) => {
      resolve(data);
    })
  }

  static reject(data) {
    return new myPromise((resolve, reject) => {
      reject(data);
    })
  }

  catch(cb) {
    return this.then(null, cb);
  }
}


myPromise.resolve(new myPromise((resolve, reject) => {
  setTimeout(() => {
    resolve('ok');
  }, 3000);
  // resolve('ok');
})).then(data => {
  console.log(data, 'success')
}, err => {
  console.log(err, 'error')
})
